package com.zb.test;

import com.zb.bean.Employee;
import org.junit.Test;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Stream;


/**
 * Stream中间操作: 多个中间操作可以连起来形成一个流水线，除非流水线上触发终止操作，否则中间操作不会执行任何处理,
 *               而在终止操作时一次性全部处理，称为“惰性求值”;
 */

public class JAVA8_8_StreamAPI_中间操作 {

    List<Employee> employees = Arrays.asList(
            new Employee(1,"zhangsan",45),
            new Employee(2,"lisi",29),
            new Employee(3,"wangwu",30),
            new Employee(4,"zhaoliu",20),
            new Employee(5,"tianqi",50),
            new Employee(6,"奥巴马",50),
            new Employee(7,"特朗普",60),
            new Employee(7,"特朗普",60),
            new Employee(7,"特朗普",60),
            new Employee(7,"特朗普",60),
            new Employee(8,"lijiu",60)
    );

    /**
     *
     * 1.筛选与切片
     *   filter: 接受Lambda，从流中过滤出需要的元素
     *   limit: 截断流，使其元素不超过给定数量
     *   skip(n): 跳过元素，返回一个扔掉钱n个元素的流。若流中元素不足n个，则返回一个空流，与limit(n)互补
     *   distinct: 筛选，通过流所生成的hashcode()和equals()去除重复元素
     */
    @Test
    public void test1(){
        Stream<Employee> stream1 = employees.stream().filter((e) -> e.getAge()>21);//过滤
       /* stream.forEach(e -> {
            System.out.println(e.getId()+" "+e.getName()+"  "+e.getAge());
        } );*/
        Stream<Employee> stream2 = stream1.skip(3);//跳过前三个元素
        Stream<Employee> stream3 = stream2.limit(5);//取前五个元素
        Stream<Employee> stream4 = stream3.distinct();//去除重复元素,需要冲洗hashcode()和equals()
        //终止操作：一次性执行全部中间操作的内容，即“惰性求值”
        // 内部迭代 迭代操作由内部Stream API完成
        stream4.forEach(System.out::println);
    }

    /**
     * 2.映射
     *  map: 接受Lambda，将元素转换成其他形式活提取信息。接收一个函数作为参数该函数会被应用到每一个元素上，并将其映射为一个新的元素
     *  flatmap: 接受一个函数作为参数，将流中的每一个元素转化为另一个流，然后把所有流连接成一个流。
     */
    @Test
    public void test2(){
        List<String> list = Arrays.asList("aaa","bbB","cCc","DDd","eEE");
        Stream<String> stream1 = list.stream().map((str) -> str.toUpperCase());
        stream1.forEach(System.out::println);

        System.out.println("===========================1==============================");

        employees.stream().map(e -> e.getName()+","+e.getAge()).forEach(System.out::println);

        System.out.println("==========================2===============================");

        //将list集合中的每个字符串元素转化为字符集合
        Stream<Stream<Character>> stream2 = list.stream().map(JAVA8_8_StreamAPI_中间操作::stringToCharacter);
        stream2.forEach((s)->s.forEach(System.out::println));

        System.out.println("=========================3================================");

        //flatMap
        Stream<Character> stream3 = list.stream().flatMap(JAVA8_8_StreamAPI_中间操作::stringToCharacter);
        stream3.forEach(System.out::println);
    }

    /**
     * 3.排序：
     *   sorted(): 自然排序（comparable）,按照字典排序
     *   sorted(Comparator com): 定制排序(Comparator)，自定义排序
     *
     */
    @Test
    public void test3(){
        //自然排序
        List<String> list = Arrays.asList("bb","Bb","1","a","A","啊");
        list.stream().sorted().forEach(System.out::println);

        //定制排序
        //先按照年龄排，年龄相同按照姓名排序
        employees.stream().sorted((e1,e2)->{
            if(e1.getAge() == e2.getAge()){
                return e1.getName().compareTo(e2.getName());
            } else{
                return Integer.compare(e1.getAge(),e2.getAge());
            }
        }).forEach(System.out::println);
    }

    public static Stream<Character> stringToCharacter(String str){
        List<Character> list = new ArrayList<>();
        for (Character c : str.toCharArray()) {
            list.add(c);
        }
        return list.stream();
    }
}
